package com.zylix.simon.drawings.notes;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Paint;
import android.graphics.Path;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import java.text.SimpleDateFormat;
import java.util.Random;
import java.io.File;
import java.io.FileOutputStream;

import com.example.android.notepad.NoteEditor;
import com.example.android.notepad.R;
import com.example.android.notepad.NotePad.NoteColumns;

public class DrawingActivity extends Activity implements View.OnTouchListener{
	private static final String TAG = "DrawingActivity";
	 /**
     * Standard projection for the interesting columns of a normal note.
     */
    private static final String[] PROJECTION = new String[] {
        NoteColumns._ID, // 0
        NoteColumns.NOTE, // 1
        NoteColumns.NOTE_TYPE, //2
        NoteColumns.TITLE, // 3
    };
    /** The index of the note column */
    private static final int COLUMN_INDEX_NOTE = 1;
    /** The index of the title column */
    private static final int COLUMN_INDEX_TITLE = 2;
    
    // This is our state data that is stored when freezing.
    private static final String ORIGINAL_CONTENT = "origContent";

    // The different distinct states the activity can be run in.
    private static final int STATE_EDIT = 0;
    private static final int STATE_INSERT = 1;

    private int mState;
    private Uri mUri;
    private Cursor mCursor;
    private EditText mText;
    private String mOriginalContent;
    
    private DrawingSurface drawingSurface;
    private DrawingPath currentDrawingPath;
    private Paint currentPaint;
    
    private static File APP_FILE_PATH = new File("/sdcard/DrawingNotes");
    private static String FileName;
    
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //Toast.makeText(DrawingActivity.this,"onCreate@DrawingActivity", Toast.LENGTH_SHORT).show();
        setContentView(R.layout.note_drawer);
        
		final Intent intent = getIntent();
        // Do some setup based on the action being performed.
        final String action = intent.getAction();
        if (Intent.ACTION_INSERT.equals(action)) {
            // Requested to insert: set that state, and create a new entry
            // in the container.
            mState = STATE_INSERT;
            mUri = getContentResolver().insert(intent.getData(), null);

            // If we were unable to create a new note, then just finish
            // this activity.  A RESULT_CANCELED will be sent back to the
            // original activity if they requested a result.
            if (mUri == null) {
                Log.e(TAG, "Failed to insert new note into " + getIntent().getData());
                finish();
                return;
            }

            // The new entry was created, so assume all will end well and
            // set the result to be returned.
            setResult(RESULT_OK, (new Intent()).setAction(mUri.toString()));

        } else {
            // Whoops, unknown action!  Bail.
            Log.e(TAG, "Unknown action, exiting");
            finish();
            return;
        }
        
        setCurrentPaint();

        drawingSurface = (DrawingSurface) findViewById(R.id.drawingSurface);
        drawingSurface.setOnTouchListener(this);
        
        // Get the note!
        mCursor = managedQuery(mUri, PROJECTION, null, null, null);
        // If an instance of this activity had previously stopped, we can
        // get the original text it started with.
        if (savedInstanceState != null) {
            mOriginalContent = savedInstanceState.getString(ORIGINAL_CONTENT);
        }
        
    }
    
    private void setCurrentPaint(){
        currentPaint = new Paint();
        currentPaint.setDither(true);
        currentPaint.setColor(0xFFFFFF00);
        currentPaint.setStyle(Paint.Style.STROKE);
        currentPaint.setStrokeJoin(Paint.Join.ROUND);
        currentPaint.setStrokeCap(Paint.Cap.ROUND);
        currentPaint.setStrokeWidth(3);
    }
    
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate menu from XML resource
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.editor_options_menu, menu);

        // Append to the
        // menu items for any other activities that can do stuff with it
        // as well.  This does a query on the system for any activities that
        // implement the ALTERNATIVE_ACTION for our data, adding a menu item
        // for each one that is found.
        Intent intent = new Intent(null, getIntent().getData());
        intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
        menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0,
                new ComponentName(this, DrawingActivity.class), null, intent, 0, null);
		return super.onCreateOptionsMenu(menu);
	}
	
    
	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
        // The user is going somewhere, so make sure changes are saved

        // If this activity is finished, and there is no draw, then we
        // simply delete the note entry.
        // Note that we do this both for editing and inserting...  it
        // would be reasonable to only do it when inserting.
        if (isFinishing() && drawingSurface.isDrawingSurfaceClean() && mCursor != null) {
            setResult(RESULT_CANCELED);
            deleteNote();
        } else {
            saveNote();
        }
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
	}

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        menu.setGroupVisible(R.id.menu_group_edit, true);
        menu.setGroupVisible(R.id.menu_group_insert, true);
        return super.onPrepareOptionsMenu(menu);
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle all of the possible menu actions.
        switch (item.getItemId()) {
        case R.id.menu_save:
        	saveNote();
            finish();
            break;
        case R.id.menu_delete:
            deleteNote();
            finish();
            break;
        case R.id.menu_revert:
        	Log.i(TAG, "hear the menu_revert!!!");
        	drawingSurface.undo();
            if( drawingSurface.hasMoreUndo() == false ){
                item.setEnabled( false );
            }
            item.setEnabled( true );
        	break;
        case R.id.menu_discard:
            cancelNote();
            finish();
            break;
        }
        return super.onOptionsItemSelected(item);
        
    }
    
    private int getRandom(int min,int max){
        long seed = System.currentTimeMillis();
        Random r = new Random(); 
        r.setSeed(seed);        
        return (min + r.nextInt(max-min+1));
    }
    
    private void updateContenProvider()
    {
        //-------Update dtatbase-------
        //-------The file name will be saved into NOTE column-------
        if (mCursor != null) {
            // Get out updates into the provider.
            ContentValues values = new ContentValues();

            //Add the note type as the text note
            values.put(NoteColumns.NOTE_TYPE, "draw");
            
            // Bump the modification time to now.
            values.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis());

            int length = FileName.length();
            // If we are creating a new note, then we want to also create
            // an initial title for it.
            if (mState == STATE_INSERT) {
            	Log.i(TAG, new Integer(length).toString());
                if (length == 0) {
                    Toast.makeText(this, R.string.nothing_to_save, Toast.LENGTH_SHORT).show();
                    return;
                }
                String title = FileName.substring(0, 21);
                values.put(NoteColumns.TITLE, title);
            }

            // Write our text back into the provider.
            values.put(NoteColumns.NOTE, FileName);

            // Commit all of our changes to persistent storage. When the update completes
            // the content provider will notify the cursor of the change, which will
            // cause the UI to be updated.
            try {
                getContentResolver().update(mUri, values, null, null);
            } catch (NullPointerException e) {
                Log.e(TAG, e.getMessage());
            }
            
        }
    }
    
    private void saveNote()
    {
    	//Toast.makeText(DrawingActivity.this,"saveNote@DrawingActivity", Toast.LENGTH_SHORT).show();
        SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd"); 
        String date = sDateFormat.format(new java.util.Date()); 
        FileName = "DrawNote-" + date + new Integer(getRandom(100,10000)).toString() + ".png";
        
        updateContenProvider();
        
        //-------Save the file into the SDcard-------        
          Handler saveHandler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
            	Toast.makeText(DrawingActivity.this,"Draw note saved!", Toast.LENGTH_LONG).show();
            }
        };
       new ExportBitmapToFile(this,saveHandler, drawingSurface.getBitmap()).execute();
    }
    
    private void deleteNote()
    {
    	if (mCursor != null) {
        mCursor.close();
        mCursor = null;
        getContentResolver().delete(mUri, null, null);
    	}    	
    }
    
    private final void cancelNote() {
        if (mCursor != null) {
                deleteNote();
        }
        setResult(RESULT_CANCELED);
        finish();
    }
    
	@Override
	public boolean onTouch(View arg0, MotionEvent motionEvent) {
        if(motionEvent.getAction() == MotionEvent.ACTION_DOWN){
            currentDrawingPath = new DrawingPath();
            currentDrawingPath.paint = currentPaint;
            currentDrawingPath.path = new Path();
            currentDrawingPath.path.moveTo(motionEvent.getX(), motionEvent.getY());
            currentDrawingPath.path.lineTo(motionEvent.getX(), motionEvent.getY());

        }else if(motionEvent.getAction() == MotionEvent.ACTION_MOVE){
            currentDrawingPath.path.lineTo(motionEvent.getX(), motionEvent.getY());
            drawingSurface.invalidate();
        }else if(motionEvent.getAction() == MotionEvent.ACTION_UP){
            currentDrawingPath.path.lineTo(motionEvent.getX(), motionEvent.getY());
            drawingSurface.addDrawingPath(currentDrawingPath);
        }

        return true;
	}

    public void onClick(View view){
        switch (view.getId()){
            case R.id.colorRedBtn:
                currentPaint = new Paint();
                currentPaint.setDither(true);
                currentPaint.setColor(0xFFFF0000);
                currentPaint.setStyle(Paint.Style.STROKE);
                currentPaint.setStrokeJoin(Paint.Join.ROUND);
                currentPaint.setStrokeCap(Paint.Cap.ROUND);
                currentPaint.setStrokeWidth(3);
            break;
            case R.id.colorBlueBtn:
                currentPaint = new Paint();
                currentPaint.setDither(true);
                currentPaint.setColor(0xFF00FF00);
                currentPaint.setStyle(Paint.Style.STROKE);
                currentPaint.setStrokeJoin(Paint.Join.ROUND);
                currentPaint.setStrokeCap(Paint.Cap.ROUND);
                currentPaint.setStrokeWidth(3);
            break;
            case R.id.colorGreenBtn:
                currentPaint = new Paint();
                currentPaint.setDither(true);
                currentPaint.setColor(0xFF0000FF);
                currentPaint.setStyle(Paint.Style.STROKE);
                currentPaint.setStrokeJoin(Paint.Join.ROUND);
                currentPaint.setStrokeCap(Paint.Cap.ROUND);
                currentPaint.setStrokeWidth(3);
            break;
        }
    }


    private class ExportBitmapToFile extends AsyncTask<Intent,Void,Boolean> {
        private Context mContext;
        private Handler mHandler;
        private Bitmap nBitmap;

        public ExportBitmapToFile(Context context,Handler handler,Bitmap bitmap) {
            mContext = context;
            nBitmap = bitmap;
            mHandler = handler;
        }

        @Override
        protected Boolean doInBackground(Intent... arg0) {
            try {
                if (!APP_FILE_PATH.exists()) {
                    APP_FILE_PATH.mkdirs();
                }
                final FileOutputStream out = new FileOutputStream(new File(APP_FILE_PATH + FileName));
                nBitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
                out.flush();
                out.close();
                return true;
            }catch (Exception e) {
                e.printStackTrace();
            }
            //mHandler.post(completeRunnable);
            return false;
        }


        @Override
        protected void onPostExecute(Boolean bool) {
            super.onPostExecute(bool);
            if ( bool ){
                mHandler.sendEmptyMessage(1);
            }
        }
    }
}
